package com.ihai.spring.boot.sample.distributed.counter.model;

import com.ihai.spring.boot.sample.distributed.counter.util.JmxRemoteUtil;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * DESC
 *
 * @author 张驰
 * @date 2019/12/23
 */
public class CounterStore {
    private ConcurrentMap<String, ICounter> counters = new ConcurrentHashMap<>();

    public ICounter addCounter(String name, long timeout) {
        if (get(name) == null) {
            synchronized (counters) {
                if (get(name) == null) {
                    ICounter counter = new Counter(timeout);
                    counter.setName(name);
                    ICounter counterProxy = new CounterProxy().getInstance(counter);
                    counters.put(name, counterProxy);
                    JmxRemoteUtil.register(counter, "iHaiCounter:name=" + counter.getName());
                }
            }
        }
        return counters.get(name);
    }

    public ICounter addCounter(ICounter counter) {
        if (get(counter.getName()) == null) {
            synchronized (counters) {
                if (get(counter.getName()) == null) {
                    JmxRemoteUtil.register(counter, "iHaiCounter:name=" + counter.getName());
                    counter = new CounterProxy().getInstance(counter);
                    counters.put(counter.getName(), counter);
                }
            }
        }
        return counters.get(counter.getName());
    }

    public ICounter get(String name) {
        ICounter counter = counters.get(name);
        if (counter != null) {
            if (!counter.isAvailable()) {
                counters.remove(counter.getName());
                JmxRemoteUtil.unRegister("iHaiCounter:name=" + counter.getName());
                counter = null;
            }
        }
        return counter;
    }

    public void remove(String name) {
        counters.remove(name);
        JmxRemoteUtil.unRegister("iHaiCounter:name=" + name);
    }

    public void reset(String name) {
        counters.get(name).reset();
    }

    public boolean contain(String name) {
        return counters.containsKey(name);
    }

    public void isMaster(boolean isMaster) {
        for (ICounter counter : counters.values()) {
            counter.isMaster(isMaster);
        }
    }
}
